package com.cheng.chengliving.commodity.exception;

import com.cheng.common.exception.ChenglivingCodeEnum;
import com.cheng.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 朱程
 * @Date: 2022/11/19/23:27
 * @Description: 1. @ResponseBody 表示以Json格式返回数据
 *               2. @ControllerAdvice 表示统一接管 basePackages包下抛出的异常
 *               3. @Slf4j 可以输出日志,便于观察调试
 */
@Slf4j
@ResponseBody
@ControllerAdvice(basePackages = "com.cheng.chengliving.commodity.controller")
public class ChenglivingExceptionControllerAdvice {

    /**
     * 1. @ExceptionHandler表示如果 basePackages包下方法抛出了指定的异常,由handleValidException来进行处理
     * 2. 数据校验异常就是 MethodArgumentNotValidException.class
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public R handleValidException(MethodArgumentNotValidException e) {

        //输出日志,观察异常信息
        //log.error("数据校验出现问题{} 异常类型是{}",e.getMessage(),e.getCause());

        //得到BindingResult
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> errorMap = new HashMap<>();

        //遍历bindingResult 将校验错误信息收集到map
        bindingResult.getFieldErrors().forEach(fieldError -> {
            errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
        });

        return R.error(ChenglivingCodeEnum.INVALID_EXCEPTION.getCode(),
                ChenglivingCodeEnum.INVALID_EXCEPTION.getMsg()).put("data",errorMap);
    }

    //说明:如果按照业务逻辑,需要去精确匹配处理异常/错误,可以再单独写方法

    /**
     * 编写方法,处理没有精确匹配的异常
     * 返回一个统一的信息,方便前端处理
     * @return
     */
    @ExceptionHandler({Throwable.class})
    public R handleException(Throwable throwable){
        return R.error(ChenglivingCodeEnum.UNKNOWN_EXCEPTION.getCode(),
                ChenglivingCodeEnum.UNKNOWN_EXCEPTION.getMsg());
    }
}
